/**
 * 
 */
package br.odb.bzk3.android;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.util.Log;
import br.odb.libscene.Actor;
import br.odb.libscene.Constants;
import br.odb.libscene.Door;
import br.odb.libscene.Sector;
import br.odb.libscene.Sector.InvalidSlotException;
import br.odb.libscene.World;
import br.odb.utils.Utils;
import br.odb.utils.math.Vec3;
import bzk3.geometry.GLES1Triangle;
import bzk3.geometry.GLES1TriangleFactory;
import bzk3.geometry.ObjMesh;

/**
 * @author monty
 * 
 */
public class GameWorld extends World {
	private ObjMesh detailMesh;
	private GameSector[] cachedSectors;
	private HashMap< String, ObjMesh >[] models;
	public GameWorld(InputStream data, InputStream detail, InputStream detailMaterials, ArrayList<Actor> people) {
		super( data, people, true );
		if ( detail != null ) {
	    	detailMesh = new ObjMesh();
	    	detailMesh.internalize( detail, detailMaterials );
	    }

	}
	public ObjMesh getDetailMesh() {
		// TODO Auto-generated method stub
		return detailMesh;
	}
	public void consolidate() {
		Log.d( "BZK3", "Consolidating doors"  );
		GameSector sector;
		GameSector another;
		GameSector master;
		int n;
		int e;

		for (int c = 1; c < getTotalSectors(); ++c) {

			sector = (GameSector) getSector(c);
			
			if ( sector.isMaster() )
				continue;

			for (int d = 0; d < 6; ++d) {
				try {
					n = sector.getLink( d );
					sector.cachedNeighBours[ d ] = (GameSector) (( n == 0 )? null : getSector( n ));
					if (sector.getDoor(d) != null) {
						
						master = (GameSector) getSector( sector.getParent() );
						
						sector.getDoor(d).setSector(sector.getLink(d));
						e = Utils.getOppositeDirection(d);
						Log.d( "BZK3", "dir:" + d + "<->" + e );
						another = (GameSector) getSector(sector.getLink(d));
						Log.d( "BZK3", "another:" + sector.getLink(d) );
						if (another.getDoor(e) != null) {
							Log.d( "BZK3", "Door consolidated between " + c + ":" + d + " and " + sector.getLink(d) + ":" + e  );
							another.setDoorAt(e, c);
							sector.getDoor(d).setLinkedDoor(another.getDoor(e));
							another.getDoor(e).setLinkedDoor(sector.getDoor(d));
						}
						
						if ( master != null && master.getDoor( d ) != null ) {
							Log.d( "BZK3", "master is " + master.getId() + ":" + d );
							( ( GameDoor ) sector.getDoor( d ) ).setMaster( (GameDoor) master.getDoor( d ) );
							( ( GameDoor ) sector.getDoor( d ).getLinkedDoor() ).setMaster( (GameDoor) master.getDoor( d ) );
							( ( GameDoor ) master.getDoor( d ) ).addSon( (GameDoor) sector.getDoor( d ) );
							( ( GameDoor ) master.getDoor( d ) ).addSon( (GameDoor) sector.getDoor( d ).getLinkedDoor() );
						} else {
							if ( another.getDoor(e) != null ) {
								master = (GameSector) getSector( another.getParent() );
								if ( master != null && master.getDoor( e ) != null ) {
									Log.d( "BZK3", "master is " + master.getId() + ":" + e );
									( ( GameDoor ) sector.getDoor( d ) ).setMaster( (GameDoor) master.getDoor( e ) );
									( ( GameDoor ) sector.getDoor( d ).getLinkedDoor() ).setMaster( (GameDoor) master.getDoor( e ) );
									( ( GameDoor ) master.getDoor( e ) ).addSon( (GameDoor) sector.getDoor( d ) );
									( ( GameDoor ) master.getDoor( e ) ).addSon( (GameDoor) sector.getDoor( d ).getLinkedDoor() );
								} else {
									Log.d( "BZK3", "1=-(" );
								}
							} else {								
								Log.d( "BZK3", "2=-(" );
							}
						}						
					}
				} catch (InvalidSlotException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
		Log.d( "BZK3", "doors consolidated" );
		cachedSectors = new GameSector[ getSectorList().size() ];
		cachedSectors = getSectorList().toArray( cachedSectors );
		setSectorList( null );
		System.gc();
	}
	
	final public int getTotalSectors() {

		if ( cachedSectors != null )
			return cachedSectors.length;
		else
			return super.getTotalSectors();
	}
	
	final public Sector getSector( int n ) {
		
		if ( cachedSectors != null )
			return cachedSectors[ n ];
		else
			return super.getSector( n );
	}

//	public void flushToGLES() {
//		GameSector sector;
//
//		for (int c = 0; c < getTotalSectors(); ++c) {
//			sector = (GameSector) getSector(c);
//			for (int d = 0; d < 6; ++d) {
//				try {
//					if (sector.getLink(d) == Constants.NO_LINK
//							|| sector.getDoor(d) != null) {
//
//					}
//				} catch (InvalidSlotException e) {
//					e.printStackTrace();
//				}
//			}
//		}
//	}
	
	public void makeDoorAt( Sector origin, int face, int sectorId, String decalName ) {
		
		super.makeDoorAt(origin, face, sectorId, decalName );
		
		if ( origin instanceof GameSector && decalName != null && decalName.length() > 0 )
			( (GameSector) origin ).setDecalAt( face, decalName );
	}

	@Override
	public Actor makeActorAt(int sector, short candelas) {
		Log.d("bzk3", "gameactor created");
		GameActor actor = new GameActor();
		actor.setCurrentSector(sector);
		actor.setEmissiveLightningIntensity(candelas);
		return actor;
	}
	

	public void applyDecalTo( Sector origin, int face, String decalName ) {

		if ( origin instanceof GameSector && decalName != null && decalName.length() > 0 )
			( (GameSector) origin ).setDecalAt( face, decalName );
	}
	
	@Override
	public Sector makeSector(float x0, float x1, float y0, float y1, float z0,
			float z1) {

		return new GameSector(x0, x1, y0, y1, z0, z1);
	}

	

//	public Sector getSectorContaining(Vec3 p) {
//		Sector sector;
//		int size = getTotalSectors();
//		for ( int c = 1; c < size; ++c ) {
//			
//			sector = getSector( c );
//			if ( sector.contains( p ) )
//				return sector;
//		}
//		
//		return getSector( 0 );
//	}
}
